﻿using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Wx.Core;
using System.Web.Security;
using Utilities.Log;
using System.Web;
namespace Wx.Api
{
    public static class Token
    {
        private static LogHelper log = new LogHelper(typeof(Token));

        public enum spocType
        {
            snsapi_base = 0,
            snsapi_userinfo = 1
        }

        public static string AccessToken
        {
            get
            {
                return GetToken();
            }
        }


        public static void Web_GetCode(HttpContextBase handler, string r_url, spocType spoc, string state = "8888")
        {
            string url = string.Format(Config.GetApiUrl("web_getcode"), Config.appid, System.Web.HttpUtility.UrlEncode(r_url), spoc == 0 ? "snsapi_base" : "snsapi_userinfo", state);
            log.info("Get WebToken!Url:" + url);
            handler.Response.Redirect(url);
        }

        public static Wx.Model.Token.WebAccessToken Web_GetToken(string code)
        {
            Wx.Model.HttpResult result = new Model.HttpResult { msg = "code is null", status = false };
            if (code != null && code != string.Empty)
            {
                string url = string.Format(Config.GetApiUrl("web_gettoken"), Config.appid, Config.secret, code);
                result = Wx.Core.HttpUtility.Get(url);
                if (result.status)
                {
                    log.info("Web_GetToken Get Msg:\r\n" + result.msg + "\r\n");
                    return JsonConvert.DeserializeObject<Wx.Model.Token.WebAccessToken>(result.msg);
                }
                else
                {
                    log.error("Web_GetToken Has error,Url:" + url);
                    return null;
                }
            }
            log.error("Web_GetToken params code is null,please checked!");
            return null;
        }

        public static Wx.Model.Token.WebAccessToken RefreshToken(string appid, string refresh_token)
        {
            Wx.Model.HttpResult result = new Model.HttpResult { msg = "code is null", status = false };
            if (refresh_token != null && refresh_token != string.Empty)
            {
                string url = string.Format(Config.GetApiUrl("refresh_token"), Config.appid, refresh_token);
                result = Wx.Core.HttpUtility.Get(url);
                if (result.status)
                {
                    log.info("Refresh token get msg:\r\n" + result.msg + "\r\n");
                    return JsonConvert.DeserializeObject<Wx.Model.Token.WebAccessToken>(result.msg);
                }
                else
                {
                    log.error("Refresh token has error,Url:" + url);
                    return null;
                }
            }
            log.error("Refresh token params refresh_token is null,please checked!");
            return null;
        }

        /// <summary>
        /// 获取access_token
        /// </summary>
        private static string GetToken()
        {
            if (Config.access_token != string.Empty && Config.access_token != null)
            {
                if (DateTime.Now < Config.get_access_time)
                {
                    log.info("Get Token By Cache,【Token:" + Config.access_token + "】");
                    return Config.access_token;
                }
                else
                {
                    Config.access_token = null;
                    return GetToken();
                }
            }
            else
            {
                string url = string.Format(Core.Config.GetApiUrl("gettoken"), "client_credential", Core.Config.appid, Core.Config.secret);
                log.info("\r\nGet Token By Remote" + url + "\r\n");
                Model.HttpResult result = Core.HttpUtility.Get(url);
                if (result.status)
                {
                    if (result.msg.Contains("errcode"))
                    {
                        Wx.Model.wxModel.wxError err = JsonConvert.DeserializeObject<Wx.Model.wxModel.wxError>(result.msg);
                        log.info("Error:GetToken【" + err.errcode + ":" + err.errmsg + "】");
                    }
                    else
                    {
                        Wx.Model.Token.accessToken accToken = JsonConvert.DeserializeObject<Wx.Model.Token.accessToken>(result.msg);
                        log.info("OK:【Token:" + accToken.access_token + "Expires In:" + accToken.expires_in + "】");
                        Core.Config.access_token = accToken.access_token;
                        Core.Config.get_access_time = DateTime.Now.AddSeconds(accToken.expires_in);
                    }
                }
                else
                {
                    log.info(result.msg);
                }
                return Config.access_token;
            }
        }

        public static bool ValiDate(string signature, string timestamp, string nonce)
        {
            string[] ArrTmp = { Config.token, timestamp, nonce };
            Array.Sort(ArrTmp);//字典排序
            string tmpStr = string.Join("", ArrTmp);
            tmpStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1");//对该字符串进行sha1加密
            tmpStr = tmpStr.ToLower();//对字符串中的字母部分进行小写转换，非字母字符不作处理
            log.info("\r\n   tmpStr:" + tmpStr + "\r\nsignature:" + signature + "\r\n");

            //WriteLog(tmpStr, Server);//计入日志
            if (tmpStr == signature)//开发者获得加密后的字符串可与signature对比，标识该请求来源于微信。开发者通过检验signature对请求进行校验，若确认此次GET请求来自微信服务器，请原样返回echostr参数内容，则接入生效，否则接入失败
            {
                return true;
            }
            else
                return false;
        }

        /// <summary>
        /// 获取安全IP列表
        /// </summary>
        private static void GetSafeIpList()
        {
            string param = "";
            Model.HttpResult result = Core.HttpUtility.Get(Core.Config.GetApiUrl("getsafeip"));
            if (result.status)
            {
                if (!result.isErrMsg())
                {
                    List<string> iplist = JsonConvert.DeserializeObject<List<string>>(result.msg);
                    foreach (var ip in iplist)
                    {
                        Core.Config.safe_ip_list.Add(ip);
                    }
                }
                else
                {
                    Model.wxModel.wxError err = JsonConvert.DeserializeObject<Model.wxModel.wxError>(result.msg);
                }
            }
            else
            {

            }
        }
    }
}
